
#include "Primitive.h"
#include "GL/gl.h"
#include <iostream>
#include <cmath>

Primitive::Primitive(PRIMITIVE_TYPE thetype, float theSize, float numdivisions)
{
    type = thetype;
    size = theSize;                            
    divisions = numdivisions;
    material = new Material();
    texture = NULL;
}

Primitive::~Primitive() {}

void Primitive::render(float timeElapsed)
{
    if (texture!=NULL) glBindTexture (GL_TEXTURE_2D, texture->getID());
    material->render(timeElapsed);
    switch(type)
    {
        case SPHERE: drawSphere();
             break;
        case CUBE: drawCube();
             break;
    }       
    float modelview[16];
    glGetFloatv(GL_MODELVIEW_MATRIX , modelview);    
    for (int i=0;i<16;i++){
        //std::cout<< i<<":" << modelview[i] << std::endl; 
    }
    pos=Vec3(modelview[12],modelview[13],modelview[14]);
}

void Primitive::update(float timeElapsed)
{ 
      std::cout << "Updating a Primitive " << std::endl;      
}

void Primitive::drawSphere()
{
       GLfloat step = 360.0/divisions;
       GLfloat radius = size/2;
       GLfloat x,y,z, c = 3.14159f/180.0f;
       for (GLfloat phi=-80.0f; phi<80.0; phi+=step)
       {
           GLfloat phi_rad = c * phi;
           GLfloat phi_rad_end = c * (phi+step);
           glBegin(GL_QUAD_STRIP);
           for (GLfloat theta=-180.0f; theta<=180.0f; theta+=step)
           {
               GLfloat theta_rad = c * theta;
               x = radius * sin(theta_rad)*cos(phi_rad);
               y = radius * cos(theta_rad)*cos(phi_rad);
               z = radius * sin(phi_rad);
               glVertex3f(x,y,z);
               x = radius * sin(theta_rad)*cos(phi_rad_end);
               y = radius * cos(theta_rad)*cos(phi_rad_end);
               z = radius * sin(phi_rad_end);
               glVertex3f(x,y,z); 
           }
           glEnd();
       }    
       
       // Close one end
       
       GLfloat closeRing_rad = c * 80.0;
       glBegin(GL_TRIANGLE_FAN);
         glVertex3f(0.0f, 0.0f, -radius);
         z = radius * -sin(closeRing_rad);
         for(GLfloat theta=-180.0f; theta<=180.0f; theta+=step)
         {
              GLfloat theta_rad = c * theta;
              x = radius * sin(theta_rad) * cos(closeRing_rad);
              y = radius * cos(theta_rad) * cos(closeRing_rad);
              glVertex3f(x,y,z);
         }
       glEnd();
       
       // Close the other
       
       glBegin(GL_TRIANGLE_FAN);
         glVertex3f(0.0f, 0.0f, radius);
         z = radius * sin(closeRing_rad);
         for(GLfloat theta=-180.0f; theta<=180.0f; theta+=step)
         {
              GLfloat theta_rad = c * theta;
              x = radius * sin(theta_rad) * cos(closeRing_rad);
              y = radius * cos(theta_rad) * cos(closeRing_rad);
              glVertex3f(x,y,z);
         }
       glEnd();
}

void Primitive::drawCube()
{
     float v = size/2;
     glBegin(GL_QUADS);
		// Front Face
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-v, -v,  v);	// Bottom Left Of The Texture and Quad
		glTexCoord2f(1.0f, 0.0f); glVertex3f( v, -v,  v);	// Bottom Right Of The Texture and Quad
		glTexCoord2f(1.0f, 1.0f); glVertex3f( v,  v,  v);	// Top Right Of The Texture and Quad
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-v,  v,  v);	// Top Left Of The Texture and Quad
		// Back Face
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-v, -v, -v);	// Bottom Right Of The Texture and Quad
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-v,  v, -v);	// Top Right Of The Texture and Quad
		glTexCoord2f(0.0f, 1.0f); glVertex3f( v,  v, -v);	// Top Left Of The Texture and Quad
		glTexCoord2f(0.0f, 0.0f); glVertex3f( v, -v, -v);	// Bottom Left Of The Texture and Quad
		// Top Face
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-v,  v, -v);	// Top Left Of The Texture and Quad
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-v,  v,  v);	// Bottom Left Of The Texture and Quad
		glTexCoord2f(1.0f, 0.0f); glVertex3f( v,  v,  v);	// Bottom Right Of The Texture and Quad
		glTexCoord2f(1.0f, 1.0f); glVertex3f( v,  v, -v);	// Top Right Of The Texture and Quad
		// Bottom Face
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-v, -v, -v);	// Top Right Of The Texture and Quad
		glTexCoord2f(0.0f, 1.0f); glVertex3f( v, -v, -v);	// Top Left Of The Texture and Quad
		glTexCoord2f(0.0f, 0.0f); glVertex3f( v, -v,  v);	// Bottom Left Of The Texture and Quad
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-v, -v,  v);	// Bottom Right Of The Texture and Quad
		// Right face
		glTexCoord2f(1.0f, 0.0f); glVertex3f( v, -v, -v);	// Bottom Right Of The Texture and Quad
		glTexCoord2f(1.0f, 1.0f); glVertex3f( v,  v, -v);	// Top Right Of The Texture and Quad
		glTexCoord2f(0.0f, 1.0f); glVertex3f( v,  v,  v);	// Top Left Of The Texture and Quad
		glTexCoord2f(0.0f, 0.0f); glVertex3f( v, -v,  v);	// Bottom Left Of The Texture and Quad
		// Left Face
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-v, -v, -v);	// Bottom Left Of The Texture and Quad
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-v, -v,  v);	// Bottom Right Of The Texture and Quad
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-v,  v,  v);	// Top Right Of The Texture and Quad
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-v,  v, -v);	// Top Left Of The Texture and Quad
	glEnd();
}
